#include <bits/stdc++.h>

using namespace std;

const int maxn=55;
const int maxm=maxn*maxn*8;
int v[maxm],c[maxm],nxt[maxm];
int g[maxn*maxn],G[maxn*maxn],en=2;
inline void addEdge(const int &x,const int &y,const int &z){
    v[en]=y;c[en]=z;nxt[en]=g[x];g[x]=en++;
    v[en]=x;c[en]=z;nxt[en]=g[y];g[y]=en++;
}

int S,T;
int dis[maxn*maxn],q[maxn*maxn];
bool build(){
    memset(dis,-1,sizeof(dis));
    int f,r;
    f=r=0;
    dis[S]=0;
    for(q[r++]=S;f<r;f++){
        const int &cur=q[f];
        for(int j=g[cur];j;j=nxt[j]){
            const int &tar=v[j];
            if((!c[j])||(dis[tar]+1)) continue;
            dis[tar]=dis[cur]+1;
            q[r++]=tar;
        }
    }
    return dis[T]!=-1;
}
uint dfs(int p,uint flow){
    uint alpha=flow,fl;
    if(p==T) return flow;
    for(int &j=G[p];j;j=nxt[j]){
        const int &tar=v[j];
        if(c[j]&&dis[tar]==dis[p]+1&&(fl=dfs(tar,min((uint)c[j],alpha)))){
            alpha-=fl;
            c[j]-=fl;
            c[j^1]+=fl;
        }
        if(!alpha) break;
    }
    return flow-alpha;
}
uint dinic(){
    uint ans=0;
    while(build()){
        memcpy(G,g,sizeof(g));
        ans+=dfs(S,~0U);
    }
    return ans;
}

int n,m;
char str[maxn][maxn];
int pnt[maxn][maxn];

int main(){
    int a,b,tot;
    scanf("%d%d%d%d",&n,&m,&a,&b);
    S=1;T=2;tot=2;
    for(int i=1;i<=n;i++){
        scanf("%s",str[i]+1);
        for(int j=1;j<=m;j++){
            pnt[i][j]=++tot;
            if(str[i][j]=='.') addEdge(S,tot,b);
            else addEdge(tot,T,b);
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<m;j++) addEdge(pnt[i][j],pnt[i][j+1],a);
    for(int j=1;j<=m;j++)
        for(int i=1;i<n;i++) addEdge(pnt[i][j],pnt[i+1][j],a);
    printf("%u\n",dinic());

    return 0;
}







